package ml;

import java.util.ArrayList;

public class TrainSampleMaker {
	/*
	 * train_interval: 每次训练后过多少周期再重新开始训练
	 */
	private int m_train_interval = 1;
	private int m_train_samples = 0;
	private int m_train_group_len = 1;
	private int m_current_train_index = 0;
	private int m_max_train_index = 0;
	private boolean m_is_rise = true;

	private ArrayList<SampleData> m_all_samples = null;
	private ArrayList<Boolean> m_all_labels = null;

	private LabelMaker m_label_maker = new LabelMaker(MLConstants.TIME_INTERVAL, MLConstants.MIN_PROFIT,
			MLConstants.MAX_LOSS);

	public TrainSampleMaker(ArrayList<SampleData> all_samples, ArrayList<Boolean> all_labels, boolean is_rise,
			int train_group_length, double train_samples_rate, int train_begin_sample, int max_train_samples,
			int train_interval) {
		assert (train_begin_sample < all_samples.size());
		assert (train_interval > 0);

		m_train_interval = train_interval;
		m_train_group_len = train_group_length;

		m_current_train_index = (train_begin_sample >= 0 ? train_begin_sample : 0);
		m_train_samples = max_train_samples;
		if ((m_current_train_index + m_train_samples > all_samples.size()) || (m_train_samples < 0)) {
			m_train_samples = all_samples.size() - m_current_train_index;
		}

		m_max_train_index = m_train_samples + m_current_train_index - 1;

		m_is_rise = is_rise;
		m_all_samples = all_samples;
		m_all_labels = all_labels;
	}

	public int GetNext(ArrayList<SampleData> train_samples, ArrayList<Boolean> train_labels,
			ArrayList<SampleData> test_samples, ArrayList<Boolean> test_labels) {
		int ret = -1;

		if (m_current_train_index + m_train_group_len < m_max_train_index) {
			ret = 0;
			train_samples.clear();
			train_labels.clear();
			test_samples.clear();
			test_labels.clear();

			// TODO: 离线训练时，可随机取一部分训练样本
			// int train_sample_num = (int) Math.ceil(m_train_samples_rate *
			// m_train_group_len);
			// ArrayList<Integer> rands =
			// DataUtil.GetMRandsFromN(train_sample_num, m_train_group_len);
			// for (int i : rands) {
			// train_samples.add(m_all_samples.get(m_current_train_index + i));
			// train_labels.add(m_all_labels.get(m_current_train_index + i));
			// }

			// 在线训练时，取之前一段时间内所有的训练样本，但最后一小段时间内的训练样本的label要重新计算。
			for (int i = m_current_train_index; i < m_current_train_index + m_train_group_len
					- MLConstants.TIME_INTERVAL; ++i) {
				train_samples.add(m_all_samples.get(i));
				train_labels.add(m_all_labels.get(i));
			}
			ArrayList<Double> tail_prices = new ArrayList<Double>(MLConstants.TIME_INTERVAL);
			for (int i = m_current_train_index + m_train_group_len - MLConstants.TIME_INTERVAL; i < m_current_train_index
					+ m_train_group_len; ++i) {
				train_samples.add(m_all_samples.get(i));
				tail_prices.add(m_all_samples.get(i).get_price());
			}
			ArrayList<Boolean> tail_labels = m_label_maker.calculate(tail_prices, 0, MLConstants.TIME_INTERVAL,
					!m_is_rise);
			train_labels.addAll(tail_labels);

			int test_num = Math
					.min(m_train_interval, m_max_train_index - m_current_train_index - m_train_group_len + 1);
			for (int j = 0; j < test_num; ++j) {
				test_samples.add(m_all_samples.get(m_current_train_index + m_train_group_len + j));
				test_labels.add(m_all_labels.get(m_current_train_index + m_train_group_len + j));
			}

			m_current_train_index += m_train_interval;
		}

		return ret;
	}
}
